package com.zh.yqbj.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.unit.DataSizeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zh.yqbj.AsyncManager.AsyncManager;
import com.zh.yqbj.VO.NoteVO;
import com.zh.yqbj.constant.StatusConstant;
import com.zh.yqbj.dto.NoteDTO;
import com.zh.yqbj.entity.Note;
import com.zh.yqbj.entity.Space;
import com.zh.yqbj.entity.SpaceNote;
import com.zh.yqbj.entity.UserSpace;
import com.zh.yqbj.mapper.NoteMapper;
import com.zh.yqbj.service.NoteService;
import com.zh.yqbj.service.SpaceNoteService;
import com.zh.yqbj.service.SpaceService;
import com.zh.yqbj.service.UserSpaceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.TimerTask;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zh
 * @since 2024-03-27 03:50:11
 */
@Service
@Slf4j
public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note> implements NoteService {

    @Autowired
    private SpaceNoteService spaceNoteService;
    @Autowired
    private SpaceService spaceService;
    @Autowired
    private UserSpaceService userSpaceService;

    @Override
    public NoteVO getNote(String noteId) {
        Note note = this.getById(noteId);
        SpaceNote spaceNote = spaceNoteService.getOne(new LambdaQueryWrapper<SpaceNote>().eq(SpaceNote::getNoteId,
                noteId));
        NoteVO noteVO = BeanUtil.copyProperties(note, NoteVO.class);
        noteVO.setSpaceId(spaceNote.getSpaceId());
        noteVO.setCreateTime(spaceNote.getCreateTime());
        noteVO.setUpdateTime(spaceNote.getUpdateTime());
        return noteVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveNote(NoteDTO noteDTO) {
        NoteService noteService = (NoteService) AopContext.currentProxy();
        // 保存笔记
        noteService.save(noteDTO);
        SpaceNote spaceNote = BeanUtil.copyProperties(noteDTO, SpaceNote.class, "id");
        spaceNote.setNoteId(noteDTO.getId());
        spaceNote.setCreateTime(LocalDateTimeUtil.now());
        spaceNote.setUpdateTime(LocalDateTimeUtil.now());
        // 保存空间-笔记中间表
        spaceNoteService.save(spaceNote);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateNote(NoteDTO noteDTO) {
        //史山处理id
        if (noteDTO.getNoteId() != null) {
            noteDTO.setId(noteDTO.getNoteId());
        } else {
            noteDTO.setNoteId(noteDTO.getId());
        }
        // 1.要么更新笔记所属空间
        LambdaUpdateWrapper<SpaceNote> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SpaceNote::getNoteId, noteDTO.getNoteId());
        updateWrapper.set(SpaceNote::getUpdateTime, LocalDateTimeUtil.now());
        updateWrapper.set(noteDTO.getSpaceId() != null, SpaceNote::getSpaceId, noteDTO.getSpaceId());
        spaceNoteService.update(updateWrapper);
        // 2.要么更新笔记信息
        // 3.先更新title content noteSize
        NoteService noteService = (NoteService) AopContext.currentProxy();
        Note note = BeanUtil.copyProperties(noteDTO, Note.class, "id");
        note.setId(noteDTO.getNoteId());
        if (note.getTitle() != null || note.getContent() != null) {
            noteService.updateById(note);
            //再根据更新的content更新size
            note = noteService.getById(note.getId());
            long contentLength = note.getContent().getBytes().length;
            String noteSize = DataSizeUtil.format(contentLength);
            log.info("笔记大小：{}", noteSize);
            note.setNoteSize(noteSize);
            noteService.updateById(note);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteNote(String noteId) {
        LambdaUpdateWrapper<SpaceNote> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SpaceNote::getNoteId, noteId);
        updateWrapper.set(SpaceNote::getStatus, StatusConstant.STATUS_DELETE);
        updateWrapper.set(SpaceNote::getUpdateTime, LocalDateTimeUtil.now());
        spaceNoteService.update(updateWrapper);
    }

    /**
     * 高度重复的代码
     * 应该抽取出来
     *
     * @param noteId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeNote(String noteId) {
        LambdaUpdateWrapper<SpaceNote> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SpaceNote::getNoteId, noteId);
        updateWrapper.set(SpaceNote::getStatus, StatusConstant.STATUS_REMOVE);
        updateWrapper.set(SpaceNote::getUpdateTime, LocalDateTimeUtil.now());
        spaceNoteService.update(updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recycleNote(String noteId) {
        LambdaUpdateWrapper<SpaceNote> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SpaceNote::getNoteId, noteId);
        updateWrapper.eq(SpaceNote::getStatus, StatusConstant.STATUS_DELETE);
        updateWrapper.set(SpaceNote::getStatus, StatusConstant.STATUS_NORMAL);
        updateWrapper.set(SpaceNote::getUpdateTime, LocalDateTimeUtil.now());
        spaceNoteService.update(updateWrapper);
    }
}
